package com.pat.java.base.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.Iterator;
import java.util.Set;

public class ServerNBlock {
	private static int port = 12000;
	public static void main(String args[]){
		
		ByteBuffer clientBuffer = ByteBuffer.allocate(1024); 
		Charset charset = Charset.forName("UTF-8");
		CharsetDecoder decoder = charset.newDecoder();  
	    CharsetEncoder encoder = charset.newEncoder();
	    ServerSocketChannel channel = null;
		Selector selector = null;
		
		try {
			selector = Selector.open();
			channel = ServerSocketChannel.open();
			channel.configureBlocking(false);		
			InetSocketAddress isa = new InetSocketAddress(port);
			channel.socket().bind(isa);
			
			//
			channel.register(selector, SelectionKey.OP_ACCEPT);
			System.out.println("Server startup.");
			while (selector.select() > 0) {
				Set<?> readyKeys = selector.selectedKeys();
				Iterator<?> readyItor = readyKeys.iterator();
				while (readyItor.hasNext()) {
					SelectionKey key = (SelectionKey) readyItor.next();
					readyItor.remove();
					
					if (key.isAcceptable()) { // 接收请求  
			            ServerSocketChannel server = (ServerSocketChannel) key.channel();  
			            System.out.println("Server wait for client.");
			            SocketChannel keyChannel = server.accept();  
			            //设置非阻塞模式  
			            keyChannel.configureBlocking(false);  
			            keyChannel.register(selector, SelectionKey.OP_READ);  
			            //keyChannel.close();
			        } else if (key.isReadable()) { // 读信息  
			            SocketChannel keyChannel = (SocketChannel) key.channel();  
			            int count = keyChannel.read(clientBuffer);  
			            if (count > 0) {  
			                clientBuffer.flip();  
			                CharBuffer charBuffer = decoder.decode(clientBuffer);  
			                System.out.println("Server accept message from Client:"+charBuffer.toString());  
			                SelectionKey sKey = keyChannel.register(selector,  SelectionKey.OP_WRITE);  
			                //sKey.attach(name); 		//将前面读取的数据保留（隐患：容易造成内存泄漏.）  
			            } else {  
			            	keyChannel.close();  
			            }
			            clientBuffer.clear();  
			        } else if (key.isWritable()) { // 写事件  
			            SocketChannel keyChannel = (SocketChannel) key.channel();  
			            //String name = (String) key.attachment();  //得到之前保留的数据
			              
			            ByteBuffer block = encoder.encode(CharBuffer.wrap("Hello ! body.I'm RMI Service")); 
			            keyChannel.write(block);  		  
			            keyChannel.close();
			        }
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				selector.close();
				channel.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}